/**************************************
 * Data Structure - Linked List
 ***/

/* Node in LinkedList - template class*/
template <typename T>
class LinkedListNode
{
public:
	LinkedListNode()
		: pNext (0){};
	LinkedListNode(const T& Elem)
		: MainField(Elem), pNext(0){}
	T MainField;
	LinkedListNode<T>* pNext;
};

/* LinkedList - template class */
template <typename T>
class LinkedList
{
public:
	LinkedList():iCount(0){}
	~LinkedList()
		{Clear();}
	void Append(const T& Elem);
	void Remove(const T& Elem);
	int GetCount()const {return iCount;}
	bool GetElement(int Position, T& Element) const;
	bool LinkedList<T>::SetElement(int Position, const T& Val);
	void Clear();
protected:
	LinkedListNode<T> HeadNode;
	int iCount;
};

/*************************************
 * Append a Node in Linked List
 * The Node is created with the Elem
 ***/
template <typename T>
void LinkedList<T>::Append(const T& Elem)
{
	LinkedListNode<T>* pNew = new LinkedListNode<T>(Elem);
	LinkedListNode<T>* pCurrent = &HeadNode;
	while(pCurrent->pNext!=0)
	{
		pCurrent = pCurrent->pNext;
	}
	pCurrent->pNext = pNew;
	iCount ++;
	return;
}

/***************************************
 * Remove the Node whose Main field is equal to Elem
 ***/
template<typename T>
void LinkedList<T>::Remove(const T& Elem)
{
	LinkedListNode<T>* pCurrent = &HeadNode;
	while(pCurrent->pNext!=0)
	{		
		if (pCurrent->pNext->MainField == Elem)
		{
			LinkedListNode<T>* pDel = pCurrent->pNext;
			pCurrent->pNext = pDel->pNext;
			delete pDel;
			pDel = 0;
			iCount--;
			return;
		}
		pCurrent = pCurrent->pNext;
	}
	return;
}

/*************************************
 * Get the Element of a certain position
 ***/
template<typename T>
bool LinkedList<T>::GetElement(int Position, T& Element)  const
{
	const LinkedListNode<T>* pCurrent = &HeadNode;
	int currentPosition = 0;
	while(pCurrent->pNext != 0)
	{
		pCurrent = pCurrent->pNext;
		currentPosition++;
		if (currentPosition == Position)
		{
			Element = pCurrent->MainField;
			return true;
		}
	}
	return false;
}

/*************************************
* Set the value of Element at a certain position
***/
template<typename T>
bool LinkedList<T>::SetElement(int Position, const T& Val)
{
	LinkedListNode<T>* pCurrent = &HeadNode;
	int currentPosition = 0;
	while(pCurrent->pNext != 0)
	{
		pCurrent = pCurrent->pNext;
		currentPosition++;
		if (currentPosition == Position)
		{
			pCurrent->MainField = Val;
			return true;
		}
	}
	return false;
}

/**********************************
 * Remove all Nodes in Linked List
 ***/
template <typename T>
void LinkedList<T>::Clear()
{
	LinkedListNode<T>* pCurrent = &HeadNode;
	while(pCurrent->pNext!= 0)
	{
		LinkedListNode<T>* pDel = pCurrent->pNext;
		pCurrent->pNext = pCurrent->pNext->pNext;
		delete pDel;
		pDel = 0;
		iCount--;
		//pCurrent =  pCurrent->pNext;
	}
}